#include <iostream>
#include <iterator>
#include <vector>
#include <list>
#include <algorithm>
#include <fstream>
#include <string>

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "CShellProcess.h"

using namespace std;

class CPipedShellCommand : public CShellProcess {
private :
	char **cmd;
	int pos;

public :
	CPipedShellCommand(string &comm) : CShellProcess(comm, 1) {
	//CPipedShellCommand(string &comm) : CShellProcess(comm) {
	};
	CPipedShellCommand(char **argv, int p) : CShellProcess(1) { 
	//CPipedShellCommand(char **argv, int p) : CShellProcess() { 
		cmd = argv;
		pos = p;
	};
	~CPipedShellCommand() {};

	virtual int read_upstream(const char *buf) {
		cout << buf;

		return 1;
	};
	virtual int read_downstream(const char *buf) {
	};
	virtual int read_errstream(const char *buf) {
		cerr << buf;

		return 1;
	};
	
	virtual void before_run() {
		if(command=="sort") {
for(long i=0;i<10000;i++) {
			write_downstream("woorung nara\n");
			write_downstream("hahahahaha\n");
			write_downstream("babo woorung\n");
}
		}
	};

	virtual void run() {
		// change process's stdin to downstream pipe
//		dup2(down_pipefd[0],0);

		// change process's stdout to upstream pipe
//		dup2(up_pipefd[1],1);


		if(command=="sort") {
			system((char *)command.c_str());
		}
		else {
			execvp("/bin/sh", cmd+pos);
		}
	};
};

int main(int argc,char *argv[])
{
	vector<CPipedShellCommand *> pv;
	string command = "sort";

	int opt;
	static char optstr[] = "e";
	int cmd_pos = -1;
	
	while((opt=getopt(argc,argv,optstr))!=-1) {
		switch(opt) {
			case 'e' :
				cmd_pos = optind;
				CPipedShellCommand *psh = new CPipedShellCommand(argv,cmd_pos);
				pv.push_back(psh);
				break;
			default :
				break;
		}
	}

	if(cmd_pos<0) {
		CPipedShellCommand *psh = new CPipedShellCommand(command);
		pv.push_back(psh);
	}
	else {
		CPipedShellCommand *psh = new CPipedShellCommand(argv,cmd_pos);
		pv.push_back(psh);
	}

	pv[0]->start();

	pv[0]->waits();	

	cout << "status after exectuion = " << pv[0]->get_status() << endl;

	delete pv[0];
}
